﻿using MongoDB.Driver;
using Sustainalytics.Entities;
using System.Collections.Generic;
using System.Linq;

namespace Sustainalytics.ScreeningTool.Synchronization.Handlers.Governance
{
    public class GovernanceIndicatorHandler : IHandlerWithGrouping<GovernanceIndicator>
    {
        public ProjectionDefinition<GovernanceIndicator> GetProjection(ProjectionDefinitionBuilder<GovernanceIndicator> builder) => builder
            .Include(x => x.Number)
            .Include(x => x.Name)
            .Include(x => x.Tickedboxes)
            .Include(x => x.Untickedboxes)
            .Include(x => x.Comment);

        public IEnumerable<ExtraElement> GetExtraElements(IEnumerable<GovernanceIndicator> entities)
            => entities.GetAnalystCommentaryExtraElements().Concat(entities.GetTickboxesExtraElements());
    }

    public static class GovernanceIndicatorExtensions
    {
        public static IEnumerable<ExtraElement> GetAnalystCommentaryExtraElements(this IEnumerable<GovernanceIndicator> entities)
            => entities.Select(x => new ExtraElement($"{x.Number} {x.Name}-Analyst commentary", x.Comment));

        public static IEnumerable<ExtraElement> GetTickboxesExtraElements(this IEnumerable<GovernanceIndicator> entities)
            => entities.SelectMany(indicator => indicator.GetTickedboxesExtraElements().Concat(indicator.GetUntickedboxesExtraElements()));

        private static IEnumerable<ExtraElement> GetTickedboxesExtraElements(this GovernanceIndicator indicator)
            => indicator.Tickedboxes.GetTickboxesExtraElements(indicator, true);

        private static IEnumerable<ExtraElement> GetUntickedboxesExtraElements(this GovernanceIndicator indicator)
            => indicator.Untickedboxes.GetTickboxesExtraElements(indicator, false);

        private static IEnumerable<ExtraElement> GetTickboxesExtraElements(this IEnumerable<KeyValuePair<string, string>> tickboxes, GovernanceIndicator indicator, bool ticked)
            => tickboxes?.Select(tickbox => tickbox.GetTickboxExtraElement(indicator, ticked)) ?? Enumerable.Empty<ExtraElement>();

        private static ExtraElement GetTickboxExtraElement(this KeyValuePair<string, string> tickbox, GovernanceIndicator indicator, bool ticked)
            => new ExtraElement($"{indicator.Number}{tickbox.Key} {tickbox.Value}", ticked);
    }
}
